package com.zmytest.service.impl;

import com.zmytest.dto.AccountDto;
import com.zmytest.dto.ResponseDto;
import com.zmytest.model.Account;
import com.zmytest.model.Role;
import com.zmytest.repository.AccountRepository;
import com.zmytest.repository.RoleRepository;
import com.zmytest.service.AccountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.LinkedList;
import java.util.List;

/**
 * Created on 2018/12/19.
 *
 * @author zhangmingyu
 *
 */
@Service
@Slf4j
public class AccountServiceImpl implements AccountService {

    private final AccountRepository accountRepository;

    private final RoleRepository roleRepository;

    @Autowired
    public AccountServiceImpl(AccountRepository accountRepository, RoleRepository roleRepository) {
        this.accountRepository = accountRepository;
        this.roleRepository = roleRepository;
    }

    @Override
    public ResponseDto<Account> create(AccountDto accountDto) {
        if (!ObjectUtils.isEmpty(accountDto.getId())) {
            return ResponseDto.fail("account id must be null");
        }
        Account account = accountRepository.findByName(accountDto.getName());
        if (!ObjectUtils.isEmpty(account)) {
            return ResponseDto.fail("account name already exist");
        }
        ResponseDto<List<Role>> roles = getRoles(accountDto);
        if (!roles.isSuccess()) {
            return ResponseDto.fail(roles.getMessage());
        }
        Account waitingSaveAccount = new Account(accountDto,roles.getData());
        Account result = accountRepository.save(waitingSaveAccount);
        return ResponseDto.success(result);
    }

    @Override
    public ResponseDto<Account> find(Long id) {
        Account account = accountRepository.getOne(id);
        return ResponseDto.success(account);
    }

    @Override
    public ResponseDto<Account> update(AccountDto accountDto) {
        Long id = accountDto.getId();
        if (ObjectUtils.isEmpty(id)) {
            return ResponseDto.fail("account id can not be null");
        }
        Account account = accountRepository.findOne(id);
        if (ObjectUtils.isEmpty(account)) {
            return ResponseDto.fail("can not find account by id["+id+"]");
        }
        ResponseDto<List<Role>> roles = getRoles(accountDto);
        if (!roles.isSuccess()) {
            return ResponseDto.fail(roles.getMessage());
        }
        account.update(accountDto,roles.getData());
        Account result = accountRepository.save(account);
        return ResponseDto.success(result);
    }

    @Override
    public ResponseDto<String> delete(Long id) {
        accountRepository.delete(id);
        return ResponseDto.success("delete success");
    }

    private ResponseDto<List<Role>> getRoles(AccountDto accountDto){
        List<Role> roles = new LinkedList<>();
        for (Long roleId : accountDto.getRoleIds()){
            Role role = roleRepository.findOne(roleId);
            if (ObjectUtils.isEmpty(role)){
                return ResponseDto.fail("can not find role by id["+roleId+"]");
            }
            roles.add(role);
        }
        return ResponseDto.success(roles);
    }
}
